'use strict'
const Service = require('egg').Service
const utility = require('utility')

/**
 * 自定义错误类型
 * @param {*} param0
 */
function MyError({ errMsg, errCode }) {
  this.message = errMsg
  this.errCode = errCode
}

/**
 * 获取n个随机数
 * @param {*} n
 * @returns
 */
function getRandoms(n = 5) {
  let result = ''
  for (let i = 0; i < n; i++) {
    result += Math.floor(Math.random() * 10)
  }
  return result
}

/**
 * 创建登录token
 * @param {*} pwd
 * @returns
 */
function createToken(pwd) {
  return utility.md5(`${pwd}&salt=WK1hg2d90l&random=${getRandoms(5)}`)
}

class UserService extends Service {
  /**
   * @description 用户注册
   * @param {String} param0
   */
  async register({ account, password }) {
    let user = await this.app.mysql.get('t_user', { account })
    user = JSON.stringify(user)
    user = JSON.parse(user)
    if (user) {
      throw new MyError({
        errCode: '100001',
        errMsg: '该帐号已经被使用',
      })
    }
    // 插入新用户
    let result = await this.app.mysql.insert('t_user', {
      account,
      password,
    })

    if (result.affectedRows !== 1) {
      return {
        retCode: '1',
        errCode: '1',
        errMsg: '注册失败',
      }
    }

    user = await this.app.mysql.get('t_user', { account })
    user = JSON.stringify(user)
    user = JSON.parse(user)

    const loginToken = createToken(password)
    result = await this.app.redis.set(`${loginToken}`, user.id)

    if (result === 'OK') {
      delete user.password
      return {
        retCode: '0',
        errCode: '0',
        errMsg: '',
        data: {
          ...user,
          token: loginToken,
        },
      }
    } else {
      return {
        retCode: '1',
        errCode: '100004',
        errMsg: result || '登录失败',
      }
    }
  }

  // 用户登录
  async login({ account, password }) {
    let user = await this.app.mysql.get('t_user', { account })
    user = JSON.stringify(user)
    user = JSON.parse(user)

    // 帐号注册
    if (!user) {
      throw new MyError({
        retCode: '1',
        errCode: '100003',
        errMsg: '该帐号未注册',
      })
    }

    // 密码不正确
    if (user.password !== password) {
      throw new MyError({
        retCode: '1',
        errCode: '100004',
        errMsg: '登录密码不正确',
      })
    }

    const loginToken = createToken(password)
    let result = await this.app.redis.set(`${loginToken}`, user.id)
    if (result === 'OK') {
      delete user.password;
      return {
        retCode: '0',
        errCode: '0',
        errMsg: 'success',
        data: {
          ...user,
          token: loginToken,
        },
      }
    } else {
      throw new MyError({
        retCode: '1',
        errCode: '100004',
        errMsg: result || '登录失败',
      })
    }
  }

  /**
   * @description 通过 token 查询 用户ID
   */
  async getUserIdByToken(token) {
    return await this.app.redis.get(token)
  }

  /**
   * 判断用户登录是否有效
   * 1. 无效 返回false
   * 2. 有效 返回用户ID
   */
  async checkLogin(token) {
    const uid = await this.app.redis.get(token)
    return uid ? uid : this.ctx.helper.error('100005', '登录已失效')
  }

  /**
   * 检测用户是否登录
   * @param {String} token 
   */
   async checkLoginState({ token }) {
    let uid = await this.getUserIdByToken(token)
    return this.ctx.helper.success({ status: uid ? 1 : 0 })
  }

  /**
   * @description 获取用户信息
   * @param {*} param0
   */
  async getUserInfo({ token }) {
    const helper = this.ctx.helper
    const service = this.ctx.service

    const userId = await this.getUserIdByToken(token)
    if (!userId) {
      return helper.error('100005', '用户未登录')
    }

    const userRes = await this.app.model.User.findOne({
      where: {
        id: userId,
      },
      attributes: {
        exclude: ['password'],
      },
    })
    const user = helper.parsePacket(userRes)
    if (!user) {
      return helper.error('100003', '帐号未注册')
    }

    const rcoinRet = await service.rcoin.totalAmount({ token })

    return helper.success({
      ...user,
      rcoinNum: rcoinRet.amount,
    })
  }
}

module.exports = UserService
